/**
 * Slugger generates header id
 */
export class Slugger {
	constructor() {
		this.seen = {};
	}

	/**
	 * @param {string} value
	 */
	serialize(value) {
		return (
			value
				.toLowerCase()
				.trim()
				// remove html tags
				.replace(/<[!\/a-z].*?>/gi, "")
				// remove unwanted chars
				.replace(
					/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,
					""
				)
				.replace(/\s/g, "-")
		);
	}

	/**
	 * Finds the next safe (unique) slug to use
	 * @param {string} originalSlug
	 * @param {boolean} isDryRun
	 */
	getNextSafeSlug(originalSlug, isDryRun) {
		let slug = originalSlug;
		let occurenceAccumulator = 0;
		if (this.seen.hasOwnProperty(slug)) {
			occurenceAccumulator = this.seen[originalSlug];
			do {
				occurenceAccumulator++;
				slug = originalSlug + "-" + occurenceAccumulator;
			} while (this.seen.hasOwnProperty(slug));
		}
		if (!isDryRun) {
			this.seen[originalSlug] = occurenceAccumulator;
			this.seen[slug] = 0;
		}
		return slug;
	}

	/**
	 * Convert string to unique id
	 * @param {object} [options]
	 * @param {boolean} [options.dryrun] Generates the next unique slug without
	 * updating the internal accumulator.
	 */
	slug(value, options = {}) {
		const slug = this.serialize(value);
		return this.getNextSafeSlug(slug, options.dryrun);
	}
}
